package com.jswdwsx.ddns.schedule;

import com.aliyun.alidns20150109.Client;
import com.aliyun.alidns20150109.models.*;
import com.jswdwsx.ddns.config.AliProperties;
import com.jswdwsx.ddns.util.IpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
public class DDNSScheduledTask {

    private final Logger logger = LoggerFactory.getLogger(DDNSScheduledTask.class);

    private final Client aliDnsClient;

    private final AliProperties aliProperties;

    public DDNSScheduledTask(Client aliDnsClient, AliProperties aliProperties) {
        this.aliDnsClient = aliDnsClient;
        this.aliProperties = aliProperties;
    }

    @Scheduled(cron = "0 */10 * * * ?")
    public void checkAndUpdateRecord() throws Exception {
        String currentHostIP = IpUtils.getCurrentHostIP();
        logger.info("Current Host IP:{}", currentHostIP);

        for (Map.Entry<String, List<String>> domain : aliProperties.getDomain().entrySet()) {

            List<DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord> record = getRecords(domain);

            for (DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord r : record) {
                // 如果本条记录是配置为要修改的二级域名的记录
                if (domain.getValue().contains(r.getRR())) {
                    updateRecord(currentHostIP, domain.getKey(), r);
                }
            }
        }
    }

    /**
     * 获取对应域名的解析记录
     *
     * @param domain 单个域名的配置信息
     * @return 解析记录
     * @throws Exception
     */
    private List<DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord> getRecords(Map.Entry<String, List<String>> domain) throws Exception {
        DescribeDomainRecordsRequest describeDomainRecordsRequest = new DescribeDomainRecordsRequest()
                .setDomainName(domain.getKey());
        // 如果只有一个二级域名要更新，直接以此为关键字查询，省去查出无需修改的记录
        if (domain.getValue().size() == 1) {
            describeDomainRecordsRequest.setKeyWord(domain.getValue().get(0));
        }

        DescribeDomainRecordsResponse descResp = aliDnsClient.describeDomainRecords(describeDomainRecordsRequest);

        return descResp.getBody().getDomainRecords().getRecord();
    }

    /**
     * 获取对应域名的解析记录
     *
     * @param currentHostIP 本机公网ip
     * @param domainName    域名
     * @param r
     * @throws Exception
     */
    private void updateRecord(String currentHostIP, String domainName, DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord r) throws Exception {
        // 如果ip没有变化
        if (currentHostIP.equals(r.getValue())) {
            logger.info("{}.{} ip({}) does not change", r.getRR(), domainName, r.getValue());
            return;
        }
        logger.info("{}.{} origin value:{}", r.getRR(), r.getDomainName(), r.getValue());
        UpdateDomainRecordRequest updateDomainRecordRequest = new UpdateDomainRecordRequest()
                .setRecordId(r.getRecordId())
                .setRR(r.getRR())
                .setValue(currentHostIP)
                .setType(r.getType());
        UpdateDomainRecordResponse updateResp = aliDnsClient.updateDomainRecord(updateDomainRecordRequest);
        logger.info("{}.{}updateResp:{}", r.getRR(), domainName, updateResp.getBody().toString());
    }
}
